package edu.bu.cs673.superkids123.parents.view;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;

import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.AbstractNavigationView;
import edu.bu.cs673.superkids123.AbstractView;
import edu.bu.cs673.superkids123.common.model.Child;
import edu.bu.cs673.superkids123.common.model.Parent;
import edu.bu.cs673.superkids123.common.model.User;
import edu.bu.cs673.superkids123.common.view.ParentsLoginView;
import edu.bu.cs673.superkids123.parents.controller.ParentSettingsController;

/*
 * 
 * @author Brent Hepburn
 * @author Ethan Rubin
 */
public class ParentSettingsView extends AbstractNavigationView implements
		ActionListener, ListSelectionListener {

	private JTable childrenTable;
	private JTable parentsTable;
	private JButton addChild;
	private JButton addParent;
	private JButton editChild;
	private JButton deleteChild;
	private JButton deleteParent;
	private JButton reportButton;
	private JButton achievementEdit;
	private JButton resourceCustomize;
	private JButton editParent;
	private JButton lockChild;

	public ParentSettingsView(AbstractFrame mainFrame) {
		super(mainFrame);
	}

	/**
	 * @wbp.parser.entryPoint
	 */
	@Override
	protected JPanel layout() {
		this.setAvatarVisible(false);

		JPanel panel = new JPanel();
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[] { 200, 20, 150, 150, 150 };
		gbl_panel.rowHeights = new int[] { 0, 125, 0, 10, 0, 125, 0 };
		panel.setLayout(gbl_panel);

		// Left Menu
		JPanel sideMenu = new JPanel(new GridLayout(10, 1, 0, 10));
		sideMenu.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		TitledBorder b = BorderFactory.createTitledBorder(" Settings ");
		sideMenu.setBorder(b);
		GridBagConstraints gbcMenu = new GridBagConstraints();
		gbcMenu.fill = GridBagConstraints.BOTH;
		gbcMenu.insets = new Insets(0, 0, 0, 20);
		gbcMenu.gridx = 0;
		gbcMenu.gridy = 0;
		gbcMenu.gridheight = 7;
		
		// Reports Button
		reportButton = new JButton("Reports");
		reportButton.addActionListener(this);
		sideMenu.add(reportButton);
		
		// Achievements Button
		achievementEdit = new JButton("Achievements");
		achievementEdit.setEnabled(true);
		achievementEdit.addActionListener(this);
		sideMenu.add(achievementEdit);

		// Resource Customize Button
		resourceCustomize = new JButton("Customization");
		resourceCustomize.addActionListener(this);
		sideMenu.add(resourceCustomize);
		
		panel.add(sideMenu, gbcMenu);

		// Right Menu
		JLabel label = new JLabel("Children:");
		GridBagConstraints gbc_label = new GridBagConstraints();
		gbc_label.anchor = GridBagConstraints.SOUTHWEST;
		gbc_label.insets = new Insets(0, 0, 5, 5);
		gbc_label.gridx = 2;
		gbc_label.gridy = 0;
		panel.add(label, gbc_label);

		childrenTable = new JTable(new ChildTableModel());
		childrenTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		childrenTable.setFillsViewportHeight(true);
		childrenTable.getTableHeader().setResizingAllowed(false);
		childrenTable.getTableHeader().setReorderingAllowed(false);
		childrenTable.getSelectionModel().addListSelectionListener(this);
		JScrollPane childrenPane = new JScrollPane(childrenTable);
		GridBagConstraints childrenGBC = new GridBagConstraints();
		childrenGBC.insets = new Insets(0, 0, 5, 5);
		childrenGBC.fill = GridBagConstraints.BOTH;
		childrenGBC.gridx = 1;
		childrenGBC.gridy = 1;
		childrenGBC.gridwidth = 6;
		panel.add(childrenPane, childrenGBC);

		addChild = new JButton("Add Child");
		addChild.addActionListener(this);
		GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
		gbc_btnNewButton.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton.gridx = 1;
		gbc_btnNewButton.gridy = 2;
		panel.add(addChild, gbc_btnNewButton);

		editChild = new JButton("Edit Child");
		editChild.setEnabled(false);
		editChild.addActionListener(this);
		GridBagConstraints gbc_btnEditChild = new GridBagConstraints();
		gbc_btnEditChild.insets = new Insets(0, 0, 5, 5);
		gbc_btnEditChild.gridx = 2;
		gbc_btnEditChild.gridy = 2;
		panel.add(editChild, gbc_btnEditChild);

		deleteChild = new JButton("Delete Child");
		deleteChild.setEnabled(false);
		deleteChild.addActionListener(this);
		GridBagConstraints gbc_btnDeleteChild = new GridBagConstraints();
		gbc_btnDeleteChild.insets = new Insets(0, 0, 5, 5);
		gbc_btnDeleteChild.gridx = 3;
		gbc_btnDeleteChild.gridy = 2;
		panel.add(deleteChild, gbc_btnDeleteChild);
		
		lockChild = new JButton("Lock/Unlock Child");
		lockChild.setEnabled(false);
		lockChild.addActionListener(this);
		GridBagConstraints gbc_btnLockChild = new GridBagConstraints();
		gbc_btnLockChild.insets = new Insets(0, 0, 5, 5);
		gbc_btnLockChild.gridx = 4;
		gbc_btnLockChild.gridy = 2;
		panel.add(lockChild, gbc_btnLockChild);
		

		JLabel lblNewLabel = new JLabel("Parents:");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.SOUTHWEST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel.gridx = 2;
		gbc_lblNewLabel.gridy = 4;
		panel.add(lblNewLabel, gbc_lblNewLabel);

		parentsTable = new JTable(new ParentTableModel());
		parentsTable.getTableHeader().setResizingAllowed(false);
		parentsTable.getTableHeader().setReorderingAllowed(false);
		parentsTable.setFillsViewportHeight(true);
		parentsTable.getSelectionModel().addListSelectionListener(this);
		JScrollPane parentsPane = new JScrollPane(parentsTable);
		GridBagConstraints parentsGBC = new GridBagConstraints();
		parentsGBC.insets = new Insets(0, 0, 5, 5);
		parentsGBC.fill = GridBagConstraints.BOTH;
		parentsGBC.gridx = 1;
		parentsGBC.gridy = 5;
		parentsGBC.gridwidth = 6;
		panel.add(parentsPane, parentsGBC);

		addParent = new JButton("Add Parent");
		addParent.addActionListener(this);
		GridBagConstraints gbc_btnNewButton_1 = new GridBagConstraints();
		gbc_btnNewButton_1.insets = new Insets(0, 0, 5, 5);
		gbc_btnNewButton_1.gridx = 1;
		gbc_btnNewButton_1.gridy = 6;
		panel.add(addParent, gbc_btnNewButton_1);

		editParent = new JButton("Edit Parent");
		editParent.addActionListener(this);
		editParent.setEnabled(false);
		GridBagConstraints gbc_btnEditParent = new GridBagConstraints();
		gbc_btnEditParent.insets = new Insets(0, 0, 5, 5);
		gbc_btnEditParent.gridx = 2;
		gbc_btnEditParent.gridy = 6;
		panel.add(editParent, gbc_btnEditParent);

		deleteParent = new JButton("Delete Parent");
		deleteParent.addActionListener(this);
		deleteParent.setEnabled(false);
		GridBagConstraints gbc_btnDeleteParent = new GridBagConstraints();
		gbc_btnDeleteParent.insets = new Insets(0, 0, 5, 5);
		gbc_btnDeleteParent.gridx = 3;
		gbc_btnDeleteParent.gridy = 6;
		panel.add(deleteParent, gbc_btnDeleteParent);

		return panel;
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		if (event.getSource() == addChild) {
			getMainFrame().getController(ParentSettingsController.class)
					.addChild();
		} else if (event.getSource() == deleteChild) {
			int selectedIndex = childrenTable.getSelectedRow();

			if (selectedIndex >= 0) {
				Child child = ((ChildTableModel) childrenTable.getModel())
						.getChild(selectedIndex);
				if (confirmDelete(child)) {
					getMainFrame()
							.getController(ParentSettingsController.class)
							.deleteUser(child);
				}
			}
		} else if (event.getSource() == editChild) {
			int selectedIndex = childrenTable.getSelectedRow();

			if (selectedIndex >= 0) {
				Child child = ((ChildTableModel) childrenTable.getModel())
						.getChild(selectedIndex);
				getMainFrame().getController(ParentSettingsController.class)
						.editChild(child);
			}
		
		}	else if (event.getSource() == lockChild) {
			int selectedIndex = childrenTable.getSelectedRow();
			if(selectedIndex >= 0) {
				Child child = ((ChildTableModel) childrenTable.getModel())
						.getChild(selectedIndex);
				getMainFrame().getController(ParentSettingsController.class).lockChild(child);
				parentsTable.revalidate();
				childrenTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
			}
			
		} else if (event.getSource() == addParent) {
			getMainFrame().getController(ParentSettingsController.class)
					.addParent();
		} else if (event.getSource() == deleteParent) {
			int selectedIndex = parentsTable.getSelectedRow();

			if (selectedIndex >= 0) {
				Parent parent = ((ParentTableModel) parentsTable.getModel())
						.getParent(selectedIndex);
				if (confirmDelete(parent)) {
					getMainFrame()
							.getController(ParentSettingsController.class)
							.deleteUser(parent);
				}
			}
		} else if (event.getSource() == editParent) {
			int selectedIndex = parentsTable.getSelectedRow();

			if (selectedIndex >= 0) {
				Parent parent = ((ParentTableModel) parentsTable.getModel())
						.getParent(selectedIndex);
				getMainFrame().getController(ParentSettingsController.class)
						.editParent(parent);
			}
		} else if (event.getSource() == reportButton) {
			getMainFrame().getController(ParentSettingsController.class)
					.viewReport();
		} else if (event.getSource() == resourceCustomize) {
			getMainFrame().changeView(CustomizationView.class);
		} else if (event.getSource() == achievementEdit) {
			getMainFrame().changeView(ManageAchievementsView.class);
		}
	}

	@Override
	public String getTitle() {
		return "Parents Console";
	}

	@Override
	public String getBorderTitle() {
		return "User information:";
	}

	protected AbstractView<? extends JComponent> initializeView() {
		super.initializeView();

		User user = authController.getCurrentUser();
		if (user == null || !(user instanceof Parent)) {
			return getMainFrame().getView(ParentsLoginView.class);
		}

		// Fall back is to return this view
		return this;
	}

	@Override
	public void valueChanged(ListSelectionEvent e) {
		ListSelectionModel lsm = (ListSelectionModel) e.getSource();

		if (lsm == childrenTable.getSelectionModel()) {
			if (!e.getValueIsAdjusting() && childrenTable.getSelectedRow() >= 0) {
				editChild.setEnabled(true);
				deleteChild.setEnabled(true);
				lockChild.setEnabled(true);
			} else if (!e.getValueIsAdjusting()) {
				editChild.setEnabled(false);
				deleteChild.setEnabled(false);
			}
		} else if (lsm == parentsTable.getSelectionModel()) {
			int row = parentsTable.getSelectedRow();
			if (!e.getValueIsAdjusting() && parentsTable.getSelectedRow() >= 0 && checkCurrentUser(row)) {
				deleteParent.setEnabled(false);
				editParent.setEnabled(true);
			} else if (!e.getValueIsAdjusting() && parentsTable.getSelectedRow() >= 0) {
				deleteParent.setEnabled(true);
				editParent.setEnabled(true);
			} else if (!e.getValueIsAdjusting()) {
				deleteParent.setEnabled(false);
				editParent.setEnabled(false);
			}
		}
	}

	private boolean checkCurrentUser(int row) {
		Parent parent = ((ParentTableModel) parentsTable.getModel())
				.getParent(row);
		if (parent != null)
			return authController.getCurrentUser().getId() == parent.getId();
		return false;
	}

	public class ChildTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 1L;
		private String[] columns = { "Name", "Age", "Gender", "Lock Status" };
		private List<Child> children = getMainFrame().getController(
				ParentSettingsController.class).getAllChildren();

		public Child getChild(int index) {
			return children.get(index);
		}

		@Override
		public String getColumnName(int col) {
			return columns[col];
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			Child child = children.get(rowIndex);
			switch (columnIndex) {
			case 0:
				return child.getName();
			case 1:
				return child.getAge();
			case 2:
				return child.getSex();
			case 3:
				return child.isLocked();
			}
			return "";
		}

		@Override
		public int getRowCount() {
			return children.size();
		}

		@Override
		public int getColumnCount() {
			return columns.length;
		}
	}

	public class ParentTableModel extends AbstractTableModel {
		private static final long serialVersionUID = 1L;
		private String[] columns = { "Name", "Email" };
		private List<Parent> parents = getMainFrame().getController(
				ParentSettingsController.class).getAllParents();

		public Parent getParent(int index) {
			return parents.get(index);
		}

		@Override
		public String getColumnName(int col) {
			return columns[col];
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			Parent parent = parents.get(rowIndex);
			switch (columnIndex) {
			case 0:
				if (authController.getCurrentUser().getId() == parent.getId())
					return parent.getName().concat(" (Current user)");
				else
					return parent.getName();
			case 1:
				return parent.getEmail();
			}
			return "";
		}

		@Override
		public int getRowCount() {
			return parents.size();
		}

		@Override
		public int getColumnCount() {
			return columns.length;
		}
	}

	private boolean confirmDelete(User user) {
		int n = JOptionPane.showConfirmDialog(null,
				"Are you sure you want to delete '" + user.getName() + "'?",
				"Logout User", JOptionPane.YES_NO_OPTION);
		if (n == JOptionPane.YES_OPTION) {
			return true;
		}
		return false;
	}
}
